// 开源地址: https://gitee.com/virus010101/linfeng-community
package io.acm.modules.app.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.acm.common.utils.ExcelParser;
import io.acm.common.utils.RR;
import io.acm.common.vo.AppUserInfoResponse;
import io.acm.common.vo.AppUserRankResponse;
import io.acm.common.vo.AppUserResponse;
import io.acm.common.utils.AppPageUtils;
import io.acm.common.utils.R;
import io.acm.modules.admin.entity.AppUserEntity;
import io.acm.modules.admin.service.AppUserService;
import io.acm.modules.app.annotation.Login;
import io.acm.modules.app.annotation.LoginUser;
import io.acm.modules.app.entity.*;
import io.acm.modules.app.param.*;
import io.acm.modules.app.service.*;
import io.acm.modules.app.utils.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.time.Year;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * APP登录接口
 *
 * @author acm
 * @date 2022/6/9 22:40
 */
@RestController
@RequestMapping("/app/user")
@Api(tags = "APP登录接口")
public class AppUserInfoController {


    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private AppUserService appUserService;
    @Autowired
    private StudentService studentService;

    @Autowired
    private StuFileService stuFileService;
    @Value("${sms.open}")
    private boolean isOpen;

    @Autowired
    private MemberService memberService;

    @Autowired
    private TeamService teamService;

    @Autowired
    private CompetionServer competionServer;

    @Autowired
    private TeamRaceService teamRaceService;

    @ApiOperation("保存队伍")
    @PostMapping("/teamsave")
    public R Teamsave(@RequestBody TeamDto teamDto){

        Integer Tid;

        //队伍名字存 返回队伍id
        String teamName = teamDto.getTeamName();
        TeamEntity team = new TeamEntity();
        team.setTeamName(teamName);
        team.setTeamStatus(0);
        LambdaQueryWrapper<TeamEntity> query = new LambdaQueryWrapper<>();
        query.eq(TeamEntity::getTeamName,teamName);
        int on = teamService.count(query);
        if(on>1) return R.error("队伍名字重复");
        boolean save = teamService.save(team);


        // 获取人员list 查询里面是否多次报名
        List<StuFileEntity> list = teamDto.getList(); System.out.println(list);
        for(StuFileEntity s : list){
            String sId = s.getSId();
            LambdaQueryWrapper<MemberEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MemberEntity::getSid,sId);
            int count = memberService.count(queryWrapper);
            if(count!=0) return  R.error("学号"+sId+"已经报名，请勿重复报名");
        }

        if(list==null) return R.error("未添加报名者");



        //加入到team表 队伍加入成功
        if(save){
            LambdaQueryWrapper<TeamEntity> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(TeamEntity::getTeamName,teamName);
            TeamEntity one = teamService.getOne(queryWrapper);

            Integer teamId = one.getTeamId();
            Tid = teamId;
        }else {
            return  R.error("队伍创建失败");
        }

        //加入到member表
        for(StuFileEntity s : list){

            LambdaQueryWrapper<StuFileEntity> queryWrapper = new LambdaQueryWrapper();
            queryWrapper.eq(StuFileEntity::getSId,s.getSId());
            int count = stuFileService.count(queryWrapper);

            if(count==0) stuFileService.save(s);
            else stuFileService.updateById(s);


            StudentEntity student = new StudentEntity();
            MemberEntity memberEntity = new MemberEntity();
            //BeanUtils.copyProperties(memberEntity,s);
            memberEntity.setMajor(s.getMajor());
            student.setMajor(s.getMajor());
            memberEntity.setGender(s.getSex());
            student.setSex(s.getSex());
            memberEntity.setEmail(s.getEmail());
            student.setEmail(s.getEmail());
            memberEntity.setCollege(s.getCollege());
            student.setCollege(s.getCollege());
            memberEntity.setName(s.getUserName());
            student.setUserName(s.getUserName());
            memberEntity.setSid(s.getSId());
            student.setSId(s.getSId());
            memberEntity.setPhone(s.getPhone());
            student.setPhone(s.getPhone());
            memberEntity.setClassName(s.getClassName());
            student.setClassName(s.getClassName());
            memberEntity.setTeamId(Tid);
            student.setRaceName(teamDto.getRaceName());
            studentService.save(student);
            memberService.save(memberEntity);
        }

        //加入到teamrace表
        String raceName = teamDto.getRaceName();
        LambdaQueryWrapper<CompetitionEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CompetitionEntity::getName,raceName);
        CompetitionEntity one = competionServer.getOne(queryWrapper);
        if(one==null) return R.error("比赛不存在");
        int raceid = one.getId();

        TeamRaceEntity teamRace = new TeamRaceEntity();
        teamRace.setTeamId(Tid);
        teamRace.setCount( teamDto.getCount());
        teamRace.setRaceid(raceid);
        teamRaceService.save(teamRace);

        return R.ok();
    }


    @ApiOperation("分页展示模糊查询的学生信息")
    @GetMapping("/stufiles")
    public RR<Page> searchStudents(
            @RequestParam(required = false) String college,
            @RequestParam(required = false) String major,
            @RequestParam(required = false) String className,
            @RequestParam(required = false) String name,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int pageSize
    ) {
        //构造分页构造器
        Page pageInfo = new Page(page,pageSize);
        //构造条件构造器
        LambdaQueryWrapper<StuFileEntity> queryWrapper = new LambdaQueryWrapper();
        //添加过滤条件
        //todo
        if(college != null) queryWrapper.like(StuFileEntity::getCollege,college);
        if(major != null) queryWrapper.like(StuFileEntity::getMajor,major);
        if(className != null) queryWrapper.like(StuFileEntity::getClassName,className);
        if(name != null) queryWrapper.like(StuFileEntity::getUserName,name);
//        for(int i=0;i<sids.size();i++){
//            queryWrapper.like(StuFileEntity::getSId, sids.get(i));
//        }
        // 调用 Service 层方法完成查询
        stuFileService.page(pageInfo,queryWrapper);

        return RR.success(pageInfo);
    }


    @ApiOperation("更新学生信息到file")
    @PostMapping("/studentupdata")
    public R updata(@RequestBody StuFileEntity student){
        LambdaQueryWrapper<StuFileEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StuFileEntity::getSId,student.getSId());
        int count = stuFileService.count(wrapper);

        if(count==0) stuFileService.save(student);
        else stuFileService.updateById(student);
        return R.ok();
    }


    @RequestMapping("/uploadExcel")
    @ApiOperation("上传学生文件信息")
    @ResponseBody
    public String handleFileUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception {
        String flag = "02";// 上传标志
        System.out.println("进入controller层 导入excel");
        System.out.println("file文件："+file);
        if (!file.isEmpty()) {
            try {
                String originalFilename = file.getOriginalFilename();// 原文件名字
                System.out.println("文件名：" + originalFilename);
//                InputStream fileStream= file.getInputStream();// 获取输入流
//                flag = departmentService.InputExcel(fileStream, originalFilename);
                List<StuFileEntity> users = ExcelParser.parseUsersFromExcel(file.getInputStream());
                stuFileService.saveBatch(users);
                System.out.println("controller层：上传成功，flag= "+flag);
                return "{\"msg\":\"ok\"}";
            } catch (Exception e) {
                flag = "03";// 上传出错
                e.printStackTrace();
                System.out.println("controller层：上传失败，flag= "+flag);
            }
        }
        return "{\"msg\":\"error\"}";
    }


    @GetMapping("/studentInfo/{sid}")
    @ApiOperation("获取学生文件中信息")
    public R studentInfo(@PathVariable("sid") String sid)  {

        //StuFileEntity response = stuFileService.getById(sid);

        String token = stuFileService.findToken();
        R r = stuFileService.searchById(sid,token);

        return r;
    }

    @ApiOperation("分页展示导入文件的学生信息")
    @GetMapping("/stufilelist")
    public RR<Page> page(int page, int pageSize,String name){

        //log.finalize("page={},pageSize={},name={}",page,pageSize,name);

        //构造分页构造器
        Page pageInfo = new Page(page,pageSize);

        //构造条件构造器
        LambdaQueryWrapper<StuFileEntity> queryWrapper = new LambdaQueryWrapper();
        //添加过滤条件
        //todo
        if(name != null) queryWrapper.like(StuFileEntity::getUserName,name);
        //添加排序条件

        //执行查询
        stuFileService.page(pageInfo,queryWrapper);

        return RR.success(pageInfo);
    }

    @ApiOperation("分页展示导入文件的学生数目")
    @GetMapping("/stuFIleCount")
    public  RR<Integer> list(StuFileEntity stuFileEntity){
        //构造条件构造器
        LambdaQueryWrapper<StuFileEntity> queryWrapper = new LambdaQueryWrapper();

        //添加过滤条件
        //todo
        //添加排序条件

        //执行查询
        int count = stuFileService.count(queryWrapper);
        //List<StuFileEntity> list = stuFileService.list((queryWrapper));

        return RR.success(count);
    }


    @ApiOperation("导出文件")
    @GetMapping("/downExcel")
    public void exportToExcel(HttpServletResponse response, @RequestParam("name") String name) {
        String decodedRacename = "";
        try {
            decodedRacename = URLDecoder.decode(name, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        LambdaQueryWrapper<CompetitionEntity> wrapper = new LambdaQueryWrapper();
        wrapper.eq(CompetitionEntity::getName,decodedRacename);
        CompetitionEntity one = competionServer.getOne(wrapper);
        int groupNumber = one.getGroupNumber();
        if(groupNumber == 1){
            try (Workbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("Student Data");

                // 创建表头
                Row headerRow = sheet.createRow(0);
                String[] columns = {"邮箱", "用户名", "密码", "姓名"};

                for (int i = 0; i < columns.length; i++) {
                    Cell cell = headerRow.createCell(i);
                    cell.setCellValue(columns[i]);
                }

                LambdaQueryWrapper<StudentEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(StudentEntity::getRaceName,name);

                // 假设你有相应的学生数据列表 studentList
                List<StudentEntity> studentList = studentService.list(queryWrapper);

                // 填充数据
                int rowNum = 1;
                int i=0,j=1;
                int currentYear = Year.now().getValue();
                String currentYearString = String.valueOf(currentYear);
                for (StudentEntity student : studentList) {
                    Row row = sheet.createRow(rowNum++);
                    if(student.getEmail() == null) row.createCell(0).setCellValue("NoEmail@123.com");
                    else row.createCell(0).setCellValue(student.getEmail());
                    //row.createCell(0).setCellValue(student.getEmail());
                    String s = currentYearString+"acm"+(char)('A'+i)+(j<10 ? "0"+j : Integer.toString(j));
                    j++;
                    if(j==51){
                        j=1;i++;
                    }
                    row.createCell(1).setCellValue(s);
                    Random random = new Random();
                    // 生成一个四位数的随机数
                    int randomNumber = random.nextInt(9000) + 1000;
                    row.createCell(2).setCellValue(randomNumber);
                    row.createCell(3).setCellValue(student.getUserName());
//                    row.createCell(2).setCellValue(student.getSId());
//                    row.createCell(3).setCellValue(student.getSex() == 1 ? "男" : "女");
//                    row.createCell(4).setCellValue(student.getCollege());
//                    row.createCell(5).setCellValue(student.getClassName());
//                    row.createCell(6).setCellValue(student.getPhone());
//                    row.createCell(7).setCellValue(student.getEmail());
                }

                response.setHeader("Content-Disposition", "attachment; filename=student-data.xlsx");
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

                workbook.write(response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            try (Workbook workbook = new XSSFWorkbook()) {
                Sheet sheet = workbook.createSheet("Student Data");

                // 创建表头
                Row headerRow = sheet.createRow(0);
//                String[] columns = {"队伍名称","比赛名称", "姓名", "学号", "性别", "学院", "班级", "手机号", "邮箱"};
                String[] columns = {"邮箱","用户名", "密码", "队伍名"};

                for (int i = 0; i < columns.length; i++) {
                    Cell cell = headerRow.createCell(i);
                    cell.setCellValue(columns[i]);
                }

                LambdaQueryWrapper<CompetitionEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(CompetitionEntity::getName,name);
                CompetitionEntity competition = competionServer.getOne(queryWrapper);
                int raceid = competition.getId();

                LambdaQueryWrapper<TeamRaceEntity> queryWrapper1 = new LambdaQueryWrapper<>();
                queryWrapper1.eq(TeamRaceEntity::getRaceid,raceid);

                List<TeamRaceEntity> list = teamRaceService.list(queryWrapper1);

                int rowNum = 1;
                int i=0,j=1;
                int currentYear = Year.now().getValue();
                String currentYearString = String.valueOf(currentYear);

                for(TeamRaceEntity teamRace : list){
                    int teamId = teamRace.getTeamId();

                    LambdaQueryWrapper<MemberEntity> queryWrapper2 = new LambdaQueryWrapper<>();
                    queryWrapper2.eq(MemberEntity::getTeamId,teamId);

                    // 假设你有相应的学生数据列表 studentList
                    List<MemberEntity> studentList = memberService.list(queryWrapper2);
                    // 填充数据
                    for (MemberEntity student : studentList) {
                        Row row = sheet.createRow(rowNum++);
                        String s = currentYearString+"acm"+(char)('A'+i)+(j<10 ? "0"+j : Integer.toString(j));
                        j++;
                        if(j==51){
                            j=1;i++;
                        }
                        if(student.getEmail() == null) row.createCell(0).setCellValue("NoEmail@123.com");
                        else row.createCell(0).setCellValue(student.getEmail());
                        row.createCell(1).setCellValue(s);
                        Random random = new Random();
                        // 生成一个四位数的随机数
                        int randomNumber = random.nextInt(9000) + 1000;
                        row.createCell(2).setCellValue(randomNumber);
                        LambdaQueryWrapper<TeamEntity> entityLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        entityLambdaQueryWrapper.eq(TeamEntity::getTeamId,student.getTeamId());
                        TeamEntity team = teamService.getOne(entityLambdaQueryWrapper);
                        //TeamEntity team = teamService.getById(student.getTeamId());
                        String teamName = team.getTeamName();
                        if(teamName==null) row.createCell(3).setCellValue("NoTeamName");
                        else row.createCell(3).setCellValue(teamName);
                    }
                }


                response.setHeader("Content-Disposition", "attachment; filename=student-data.xlsx");
                response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

                workbook.write(response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    @ApiOperation("保存学生")
    @PostMapping("/studentsave")
    public R save(@RequestBody StudentEntity student){
        LambdaQueryWrapper<StudentEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StudentEntity::getRaceName,student.getRaceName());
        queryWrapper.eq(StudentEntity::getSId,student.getSId());
        int count = studentService.count(queryWrapper);
        if(count == 1) return  R.error("已经报名，请勿重复报名");
        studentService.save(student);

        studentService.studentTostufIle(student);
        return R.ok();
    }

    @ApiOperation("分页展示报名学生数目")
    @GetMapping("/studentCount")
    public  RR<Integer> list(StudentEntity studentEntity){
        //构造条件构造器
        LambdaQueryWrapper<StudentEntity> queryWrapper = new LambdaQueryWrapper();

        //添加过滤条件
        //todo
        //添加排序条件

        //执行查询
        int count = studentService.count(queryWrapper);
        //List<StuFileEntity> list = stuFileService.list((queryWrapper));

        return RR.success(count);
    }
    @ApiOperation("分页展示报名学生信息")
    @GetMapping("/studentlist")
    public RR<Page> Page(int page, int pageSize,String name){

        //log.finalize("page={},pageSize={},name={}",page,pageSize,name);

        //构造分页构造器
        Page pageInfo = new Page(page,pageSize);

        //构造条件构造器
        LambdaQueryWrapper<StudentEntity> queryWrapper = new LambdaQueryWrapper();
        //添加过滤条件
        //todo
        //if(name != null) queryWrapper.like(StuFileEntity::getUserName,name);
        //添加排序条件
        if(name != null)
        queryWrapper.eq(StudentEntity::getRaceName,name);
        //执行查询
        studentService.page(pageInfo,queryWrapper);

        return RR.success(pageInfo);
    }



    @PostMapping("/sendSmsCode")
    @ApiOperation("测试发送验证码")
    public R sendSmsCode(@RequestBody SendCodeForm param) {
        String code = appUserService.sendSmsCode(param);
        if (isOpen) {
            //TODO
            //send Aliyun Sms code
        }
        return R.ok("测试验证码:" + code);
    }


    /**
     * 手机验证码登录
     */
    @PostMapping("/smsLogin")
    @ApiOperation("手机验证码登录")
    public R smsLogin(@RequestBody SmsLoginForm form, HttpServletRequest request) {

        //用户登录
        Integer userId = appUserService.smsLogin(form, request);

        //生成token
        String token = jwtUtils.generateToken(userId);

        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());

        return R.ok(map);
    }

    /**
     * 微信小程序登录
     */
    @PostMapping("/miniWxlogin")
    @ApiOperation("手机验证码登录")
    public R miniWxLogin(@RequestBody WxLoginForm form) {

        //用户登录
        Integer userId = appUserService.miniWxLogin(form);

        //生成token
        String token = jwtUtils.generateToken(userId);

        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", jwtUtils.getExpire());

        return R.ok(map);
    }

    @Login
    @GetMapping("/userInfo")
    @ApiOperation("获取用户信息")
    public R userInfo(@ApiIgnore @LoginUser AppUserEntity user) {
        AppUserEntity u = appUserService.getById(user.getUid());
        AppUserResponse response = appUserService.getUserInfo(u);
        return R.ok().put("result", response);
    }

    @Login
    @PostMapping("/cancelFollow")
    @ApiOperation("取消关注用户")
    public R cancelFollow(@ApiIgnore @LoginUser AppUserEntity user,
                          @RequestBody AddFollowForm request) {
        appUserService.cancelFollow(request, user);
        return R.ok("取消关注用户成功");
    }

    @Login
    @PostMapping("/userInfoEdit")
    @ApiOperation("用户修改个人信息")
    public R userInfoEdit(@ApiIgnore  @LoginUser AppUserEntity user, @RequestBody AppUserUpdateForm appUserUpdateForm) {
        appUserService.updateAppUserInfo(appUserUpdateForm, user);
        return R.ok("修改成功");
    }


    @Login
    @PostMapping("/addFollow")
    @ApiOperation("关注用户")
    public R addFollow(@ApiIgnore  @LoginUser AppUserEntity user, @RequestBody AddFollowForm request) {
        appUserService.addFollow(request, user);
        return R.ok("关注用户成功");
    }




    @Login
    @GetMapping("/userFans")
    @ApiOperation("我的粉丝分页列表")
    public R userFans(@RequestParam("page") Integer page, @ApiIgnore @LoginUser AppUserEntity user) {

        AppPageUtils pages = appUserService.userFans(page, user.getUid());
        return R.ok().put("result", pages);
    }

    @Login
    @GetMapping("/follow")
    @ApiOperation("我的关注分页列表")
    public R follow(@RequestParam("page") Integer page,
                    @ApiIgnore @LoginUser AppUserEntity user) {

        AppPageUtils pages = appUserService.follow(page, user);
        return R.ok().put("result", pages);
    }


    @Login
    @PostMapping("/userInfoById")
    @ApiOperation("用户个人主页信息")
    public R userInfoById(@RequestBody AppUserInfoForm request,
                          @ApiIgnore @LoginUser AppUserEntity user) {
        AppUserInfoResponse response = appUserService.findUserInfoById(request.getUid(), user);

        return R.ok().put("result", response);
    }


    @Login
    @PostMapping("/userRank")
    @ApiOperation("发帖达人列表")
    public R userRank() {
        List<AppUserRankResponse> list=appUserService.userRank();
        return R.ok().put("result",list);
    }

}
